package jp.co.ricoh.melody.models;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.List;

import jp.co.ricoh.melody.models.tables.ITables;

/**
 * Created by leonard on 17-3-11.
 */

public abstract class BaseModel<T extends BaseModel> implements IBaseModel<T>,ITables {

    @Override
    public SQLiteDatabase getDatabase(){
        return null;
    }

    @Override
    public int delete(int id) {
        return getDatabase().delete(getTableName(), getIdName() + S_EQUALS + S_PARAM, new String[]{convertToString(id)});
    }

    @Override
    public T query(int id) {
        String[] columnNames = getColumnNames();
        Cursor cursor = getDatabase().query(getTableName(), columnNames, getIdName() + S_EQUALS + S_PARAM, new String[]{convertToString(id)}, null, null, null);
        ContentValues contentValues = null;
        if(cursor.moveToNext()){
            contentValues = cursorToContentValues(columnNames,getColumnTypes(), cursor);
        }
        if (contentValues == null){
            return null;
        }else {
            return newInstance(contentValues);
        }
    }

    private ContentValues cursorToContentValues(String[] columnNames, TableType[] columnTypes, Cursor cursor) {
        ContentValues contentValues = new ContentValues();
        for (int i = 0; i < columnNames.length; i++) {
            int index = cursor.getColumnIndexOrThrow(columnNames[i]);
            TableType tableType = columnTypes[i];
            switch (tableType){
                case STRING:
                    contentValues.put(columnNames[i],cursor.getString(index));
                    break;
                case SHORT:
                    contentValues.put(columnNames[i],cursor.getShort(index));
                    break;
                case LONG:
                    contentValues.put(columnNames[i],cursor.getLong(index));
                    break;
                case FLOAT:
                    contentValues.put(columnNames[i],cursor.getFloat(index));
                    break;
                case DOUBLE:
                    contentValues.put(columnNames[i],cursor.getDouble(index));
                    break;

                case BLOB:
                    contentValues.put(columnNames[i],cursor.getBlob(index));
                    break;
            }
        }
        return contentValues;
    }


    @Override
    public long add(T entry) {
        return getDatabase().insert(getTableName(), null, entry.toContentValues());
    }

    @Override
    public int update(T entry) {
        return getDatabase().update(getTableName(), entry.toContentValues(), entry.getIdName() + S_EQUALS + S_PARAM, new String[]{convertToString(entry.getId())});
    }

    @Override
    public List<T> queryAll() {
       ArrayList<T> list = new ArrayList<>();
        Cursor cursor = getDatabase().query(getTableName(), getColumnNames(),null, null, null, null, null);
        while (cursor.moveToNext()){
            ContentValues contentValues = cursorToContentValues(getColumnNames(), getColumnTypes(), cursor);
            if (contentValues!=null) {
                T instance = newInstance(contentValues);
                list.add(instance);
            }
        }
        return list;
    }

    @Override
    public List<T> queryBySql(String sql) {
        ArrayList<T> list = new ArrayList<>();
        Cursor cursor = getDatabase().rawQuery(sql, null);
        while (cursor.moveToNext()){
            ContentValues contentValues = cursorToContentValues(getColumnNames(), getColumnTypes(), cursor);
            if (contentValues!=null) {
                T instance = newInstance(contentValues);
                list.add(instance);
            }
        }
        return list;
    }

    String convertToString(Object o){
        return String.valueOf(o);
    }

}
